const PENDING='pending';
const FULFILLED='fulfilled';
const REJECTED='reject';
class MyPromise{
    constructor(executer){//通过构造函数接受执行器 executer代表执行起
        try{
            executer(this.resolve,this.reject)
        }catch(e){
            this.reject(e)
        }
        
    }
    status=PENDING;
    //成功以后的值
    value=undefined;
    //失败之后的原因
    reason=undefined;
    //成功的回调函数
    successCallback=[];
    //失败的回调函数
    failCallback=[];
    resolve=(value)=>{  
        //如果状态不是等待 阻止执行
        if(this.status!==PENDING) return
        //将状态更改为成功
        this.status=FULFILLED
        //保存成功之后的值
        this.value=value;
        //判断成功回调是否存在 如果存在调用
        //this.successCallback && this.successCallback(this.value) 
        while(this.successCallback.length){
            this.successCallback.shift()(this.value) 
            //shift() 方法用于把数组的第一个元素从其中删除，并返回第一个元素的值。
        }
    }
    reject=(reason)=>{
        //如果状态不是等待 阻止执行
        if(this.status!==PENDING) return
        this.status=REJECTED
        //保存失败后的原因
        this.reason=reason;
        //判断失败回调是否存在 如果存在调用
        //this.failCallback && this.failCallback(this.value);
        while(this.failCallback.length){
            this.failCallback.shift()(this.reason)
        }
    }
    then(successCallback,failCallback){
        successCallback = successCallback ? successCallback : value=>value;
        failCallback=failCallback ? failCallback : reason=>{throw reason}
        let promise2=new MyPromise((resolve,reject)=>{
            //判断状态
            if(this.status===FULFILLED){
                setTimeout(()=>{
                    try{
                        let x=successCallback(this.value);
                        //判断x的值是普通值还是promise对象
                        //如果是普通值 直接调用resolve 将其转换成promise对象
                        //如果是promise对象 查看promise对象返回的结果
                        //再根据promise对象返回的结果 决定调用resolve还是调用reject
                        resolvePromise(promise2,x,resolve,reject)
                    }catch(e){
                        reject(e)
                    }
                    
                },0)
                
            }else if(this.status===REJECTED){
                setTimeout(()=>{
                    try{
                        let x=failCallback(this.reason);
                        //判断x的值是普通值还是promise对象
                        //如果是普通值 直接调用resolve 将其转换成promise对象
                        //如果是promise对象 查看promise对象返回的结果
                        //再根据promise对象返回的结果 决定调用resolve还是调用reject
                        resolvePromise(promise2,x,resolve,reject)
                    }catch(e){
                        reject(e)
                    }
                    
                },0)
                
            }else {
                //等待
                //将成功 失败 回调函数存储起来;
                this.successCallback.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x=successCallback(this.value);
                            //判断x的值是普通值还是promise对象
                            //如果是普通值 直接调用resolve 将其转换成promise对象
                            //如果是promise对象 查看promise对象返回的结果
                            //再根据promise对象返回的结果 决定调用resolve还是调用reject
                            resolvePromise(promise2,x,resolve,reject)
                        }catch(e){
                            reject(e)
                        }
                        
                    },0)
                });
                this.failCallback.push(()=>{
                    setTimeout(()=>{
                        try{
                            let x=failCallback(this.reason);
                            //判断x的值是普通值还是promise对象
                            //如果是普通值 直接调用resolve 将其转换成promise对象
                            //如果是promise对象 查看promise对象返回的结果
                            //再根据promise对象返回的结果 决定调用resolve还是调用reject
                            resolvePromise(promise2,x,resolve,reject)
                        }catch(e){
                            reject(e)
                        }
                        
                    },0)
                });
            }
        });
        
        return promise2;
    
    
    
    }
    finally(callback){
        return this.then((value)=>{
            return MyPromise.resolve(callback()).then(()=>value)
            callback();
        },(reason)=>{
            return MyPromise.resolve(callback()).then(()=>{throw reason})
            callback()
        })
    }
    catch(failCallback){
       return this.then(undefined,failCallback)
    }
    static all(array){
        let result=[];
        let index=0;
        
        return new MyPromise(function(resolve,reject){
            function addData(key,value){
                index++;
                result[key]=value;
                if(index===array.length){
                    resolve(result)
                }
            }
            for(let i=0;i<array.length;i++){
                let current=array[i];
                if(current instanceof MyPromise){  //如果是promise对象
                    current.then(value=>addData(i,value),(reason)=>{reject(reason)})
                }else{ //普通值 添加到数组中
                    addData(i,array[i]); 
                }
            }
        })
    }

    static resolve(value){
        if(value instanceof MyPromise) return value;
        return new MyPromise(resolve=>resolve(value))
    }
}
function resolvePromise(promise2,x,resolve,reject){
    if(promise2===x){//判断返回的是否返回本身promise对象
        return reject(new TypeError('error')) //如果是阻止代码进行 输出错误信息
    }
    if(x instanceof MyPromise){
        //promise 对象
        // x.then((value)=>{
        //     resolve(value)
        // },(reason)=>{
        //     reject(reason)
        // })
        x.then(resolve,reject)
    }else{
        resolve(x)
    }
}

module.exports=MyPromise;